home *** CD-ROM | disk | FTP | other *** search
- ; Utility Macros - Version 1.0 - for Microsoft Macro Assembler 6.0
- ; (C) Copyright Microsoft Corporation, 1987,1988,1989,1990
-
- ;* @ArgCount - Macro function returns the number of arguments in a
- ;* VARARG list.
- ;*
- ;* Params: arglist - arguments to be counted
-
- @ArgCount MACRO arglist:VARARG
- LOCAL count
- count = 0
- FOR arg, <arglist>
- count = count + 1
- ENDM
- EXITM %count
- ENDM
-
- ;* @ArgI - Macro function returns an argument specified by number
- ;* from a VARARG list.
- ;*
- ;* Shows: Directives - FOR LOCAL EXITM
- ;* TEXTEQU =
- ;* Operator - EQ
- ;*
- ;* Params: index - one-based number of the argument to be returned
- ;* arglist - argument list
-
- @ArgI MACRO index:REQ, arglist:VARARG
- LOCAL count, retstr
- count = 0
- FOR arg, <arglist>
- count = count + 1
- IF count EQ index
- retstr TEXTEQU <arg>
- ENDIF
- ENDM
- EXITM retstr
- ENDM
-
- ;* @ArgRev - Macro function returns a reversed order version of a
- ;* VARARG list.
- ;*
- ;* Shows: Operators - <> ! %
- ;* String directive - SUBSTR
- ;* Predefined function - @SizeStr
- ;*
- ;* Params: arglist - arguments to be reversed
-
- @ArgRev MACRO arglist
- LOCAL txt, arg
- txt TEXTEQU <>
- % FOR arg, arglist
- txt CATSTR <arg>, <!,>, txt
- ENDM
-
- txt SUBSTR txt, 1, @SizeStr( %txt ) - 1
- txt CATSTR <!<>, txt, <!>>
- EXITM txt
- ENDM
-
- ;* @SaveRegs and @RestoreRegs - Macros to save and restore a list
- ;* of macros. @SaveRegs pushes each register in the argument list.
- ;* and saves each register name in a text macro. @RestoreRegs uses
- ;* the saved register list to pop each register.
- ;*
- ;* Shows: Directives - CATSTR INSTR
- ;*
- ;*
- ;* Params: For @SaveRegs, the registers to be pushed
- ;* For @RestoreRegs, none
-
- pregs TEXTEQU <> ; Initialize global text macro to empty
-
- @SaveRegs MACRO regs:VARARG
- LOCAL reg
- pregs CATSTR <!<>, <regs>, <!>>
- % FOR reg, <regs>
- push reg ;; Push each register
- ENDM
- ENDM
-
- @RestoreRegs MACRO
- LOCAL reg
- % FOR reg, @ArgRev( pregs ) ;; @ArgRev from MACROS.INC
- pop reg ;; Pop each register
- ENDM
- ENDM
-
- ;* @PushAll and @PopAll - Macros to push and pop all general purpose
- ;* registers. Registers are pushed in the following order:
- ;* AX, CX, DX, BX, SP, BP, SI, DI
- ;* They are popped in the reverse order. Uses most efficient method
- ;* available at assembly time (not at run time).
- ;*
- ;* Shows: Instruction - pusha popa
- ;* Operator - AND
- ;*
- ;* Params: None
-
- @PushAll MACRO
- IF @Cpu AND 00000010y ;; If assembling on 80186/286/386,
- pusha ;; use efficient PUSHA
- ELSE ;; Otherwise push individually
- push ax
- push cx
- push dx
- push bx
- push sp
- push bp
- push si
- push di
- ENDIF
- ENDM
-
- @PopAll MACRO
- IF @Cpu AND 00000010y ;; If assembling on 80186/286/386,
- popa ;; use efficient POPA
- ELSE ;; Otherwise pop individually
- pop di
- pop si
- pop bp
- pop sp
- pop bx
- pop dx
- pop cx
- pop ax
- ENDIF
- ENDM
-
- ;* echof - Macro to display assembly-time value of expressions. The
- ;* syntax is similar to the C printf function. Useful for debugging
- ;* macros. For example, the following line displays the SIZE of an
- ;* array:
- ;* echof <The value of $ is $>, (SIZE array), %(SIZE array)
- ;*
- ;* Params: format - Text to be displayed with a $ placeholder for
- ;* each expression to be evaluated and inserted.
- ;* args - List of expressions to be evaluated. Text of
- ;* each value will be inserted into the format.
-
- echof MACRO format:REQ, args:VARARG
- LOCAL string, pos, lastpos
-
- ;; Initialize variables
- pos = 1
- string TEXTEQU <>
- ;; Loop through, finding $ and building output string
- FOR val, <args>
- ;; If beyond end of format string, exit FOR loop
- IF pos GE @SizeStr( format )
- pos = 0
- EXITM
- ENDIF
- ;; Save last position and find the next $
- lastpos = pos
- pos = @InStr( pos, format, <$> )
- ;; If $ not found, exit FOR loop
- IF pos EQ 0
- EXITM
- ENDIF
- ;; Append text up the next $
- string CATSTR string, @SubStr( format, lastpos, pos - lastpos )
- ;; Append matching value and skip past $
- string CATSTR string, <val>
- pos = pos + 1
- ENDM
- IF pos
- ;; Attach any trailing characters
- IF pos LE @SizeStr( format )
- string CATSTR string, @SubStr( format, pos )
- ENDIF
- ;; Display the finished string
- % ECHO string
- ELSE
- ECHO echof error: $ count does not match argument count
- ENDIF
- ENDM
-
- ;* Equates for conditional handling of pointers
-
- IF @DataSize
- lesIF TEXTEQU <les>
- ldsIF TEXTEQU <lds>
- esIF TEXTEQU <es:>
- ELSE
- lesIF TEXTEQU <mov>
- ldsIF TEXTEQU <mov>
- esIF TEXTEQU <>
- ENDIF
-
- ;* pushc - Macro that pushes a constant using the most efficient
- ;* method for the current processor. The 80286 version pushes
- ;* directly. Since this is illegal on the 8086, this version pushes
- ;* through AX.
- ;*
- ;* Shows: Operator - OPATTR
- ;* Text macro - @Cpu
-
- IF @Cpu AND 00000010y
- pushc MACRO op ;; 80186 or higher
- push op
- ENDM
- ELSE
- pushc MACRO op ;; 8088/8086
- IFE (OPATTR (adr)) AND 00000100y
- mov ax, op ;; If it's really a constant
- push ax ;; push through register
- ELSE
- push op ;; If not constant, push normal
- ENDIF
- ENDM
- ENDIF
-